package weightmanager;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 
 * @author Lasse Poulsen
 * 
 */
public class TCPClient {
	private Socket clientSocket;
	private DataOutputStream outputStream;
	private BufferedReader inputStream;
	private Thread thread;
	private ConcurrentLinkedQueue<String> inputQueue = new ConcurrentLinkedQueue<String>();
	// private Queue<String> inputQueue = new LinkedList<String>();
	private ConcurrentLinkedQueue<String> outputQueue = new ConcurrentLinkedQueue<String>();

	// private Queue<String> outputQueue = new LinkedList<String>();

	/**
	 * Creates a TCP socket connection to the given server name and port, it
	 * then starts a {@link TCPClientThread} to handle reading and writing to
	 * the server
	 * 
	 * @param host
	 *            String format name of the server.
	 * @param port
	 *            TCP port number to connect to
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public TCPClient(String host, int port, boolean crlf) throws UnknownHostException, IOException {
		clientSocket = new Socket(host, port);
		outputStream = new DataOutputStream(clientSocket.getOutputStream());
		inputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

		thread = new Thread(new TCPClientThread(inputStream, outputStream, inputQueue, outputQueue));
		thread.start();
	}

	public TCPClient(String host, int port) throws UnknownHostException, IOException {
		this(host, port, true);
	}

	public String waitForLine(int millis) {
		int waited = 0;
		while (waited < millis) {
			if (this.getLineAvalible())
				return this.getLine();
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
			}
			waited += 50;
		}
		return null;
	}

	/**
	 * Check to see if there are line(s) avalible from the server.
	 * 
	 * @return
	 */
	public boolean getLineAvalible() {
		return !inputQueue.isEmpty();
	}

	/**
	 * Get a line from the server, this value will be NULL if there are no more
	 * lines in the queue.
	 * 
	 * @return
	 */
	public String getLine() {
		return inputQueue.poll();
	}

	/**
	 * Send a line to the server.
	 * 
	 * @param line
	 */
	public void sendLine(String line) {
		outputQueue.add(line);
	}

	/**
	 * Interrupt the server connection thread to make it close correctly.
	 */
	public void close() {
		thread.interrupt();
	}
}